<template>
  <div>
    <h3>实时产量(机加线)</h3>
    <el-col :span="24">
      <div class="block">
        <el-date-picker
          v-model="value2"
          type="datetimerange"
          :shortcuts="shortcuts"
          range-separator="To"
          start-placeholder="起始日期"
          end-placeholder="结束日期"
          :default-time="['00:00:00', '00:00:00']" 
        />
        <el-select v-model="selectedLine" placeholder="选择生产线" style="width: 240px">
          <el-option v-for="item in lineOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
    </el-col>
    <div ref="chart" style="height: 500px; width: 1300px"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import * as echarts from "echarts";
import axios from "axios";

const value2 = ref([]);
const shortcuts = [
  {
    text: "当天",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      return [start, now];
    },
  },
];

const selectedLine = ref('CBM1');
const lineOptions = [
  {value: "CBM1", label: "缸体M1"},
  {value: "CBM2", label: "缸体M2"},
  {value: "CHM1", label: "缸盖M1"},
  {value: "CHM2", label: "缸盖M2"},
  {value: "CS", label: "曲轴"},
];

const filteredAssets = ref(['CBM2CONVY_2', 'CBM2CONVY_1', 'CBM2CONVY_3', 'CBM1CONVY_1', 'CBM1CONVY_2', 'CHM2CONVY_2']);

const chart = ref(null);
let chartInstance;

function extractOpNumber(asset: string): string {
  const opIndex = asset.indexOf('OP');
  return opIndex >= 0 ? asset.substring(opIndex) : asset;
}

function sortAssets(assets: string[]): string[] {
  return assets.sort((a, b) => {
    const opA = extractOpNumber(a);
    const opB = extractOpNumber(b);
    
    const numA = parseInt(opA.match(/\d+/)?.[0] || '0');
    const numB = parseInt(opB.match(/\d+/)?.[0] || '0');
    
    if (numA !== numB) {
      return numA - numB;
    }
    
    const letterA = opA.match(/[A-Za-z]+$/)?.[0] || '';
    const letterB = opB.match(/[A-Za-z]+$/)?.[0] || '';
    return letterA.localeCompare(letterB);
  });
}

function initChart(data) {
  if (!chart.value) return;
  
  if (chartInstance) {
    chartInstance.dispose();
  }
  
  chartInstance = echarts.init(chart.value);

  const allAssets = new Set();
  data.forEach(dayData => {
    dayData.hours.forEach(hourData => {
      Object.keys(hourData.assets).forEach(asset => {
        if (!filteredAssets.value.includes(asset)) {
          allAssets.add(asset);
        }
      });
    });
  });
  const assetList = sortAssets(Array.from(allAssets));
  const selectedLineLabel = lineOptions.find(item => item.value === selectedLine.value)?.label || selectedLine.value;

  const option = {
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        const assetName = params[0].name;
        let result = `<div>${extractOpNumber(assetName)}</div>`;
        params.forEach(param => {
          const datePart = param.seriesName.split('|')[0] || '';
          const timePart = param.seriesName.split('|')[1] || param.seriesName;
          result += `<div>${datePart} ${timePart}: ${param.value}</div>`;
        });
        return result;
      },
    },
    legend: {
      data: [], 
      orient: 'vertical',
      right: '10',
      top: 'center',
      formatter: function(name) {
        return name.split('|')[1] || name;
      }
    },
    title: {
      text: `${selectedLineLabel} 产量统计`,
      left: 'center',
      textStyle: {
        color: 'black',
      },
      subtext: '单位：台',
      subtextStyle: {
        fontWeight: 'bold',
      },
    },
    xAxis: {
      name: '设备',
      type: 'category',
      axisLabel: {
        rotate: 45,
        interval: 0,
        formatter: (value: string) => extractOpNumber(value)
      },
      data: assetList,
    },
    yAxis: {
      type: 'value',
    },
    series: [],
    dataZoom: [
      {
        type: 'slider',  
        show: true,      
        start: 0,
        end: 100,
        top: '97%'       
      },
      {
        type: 'inside',
        start: 90,
        end: 100,
      },
    ],
  };

  const timeSlotsAdded = new Set();

  data.forEach((dayData) => {
    dayData.hours.forEach((hourData) => {
      const filteredAssetsData = {};
      Object.keys(hourData.assets).forEach(asset => {
        if (!filteredAssets.value.includes(asset)) {
          filteredAssetsData[asset] = hourData.assets[asset];
        }
      });

      const seriesData = assetList.map(asset => filteredAssetsData[asset] || 0);
      
      if (seriesData.some(value => value > 0)) {
        const timeSlot = hourData.timeRange;
        
        const seriesName = `${dayData.date}|${timeSlot}`;
        
        option.series.push({
          name: seriesName,
          type: 'bar',
          stack: 'total',
          data: seriesData,
        });

        if (!timeSlotsAdded.has(timeSlot)) {
          option.legend.data.push(seriesName);
          timeSlotsAdded.add(timeSlot);
        }
      }
    });
  });

  chartInstance.setOption(option);
  
  window.addEventListener('resize', function() {
    chartInstance.resize();
  });
}
  
onMounted(() => {
  value2.value = [new Date(new Date().setHours(8, 0, 0, 0)), new Date()];
  fetchData();
});

function formatDate(d: string) {
  const date = new Date(d);
  const YY = date.getFullYear() + "-";
  const MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
  const DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
  const hh = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
  const mm = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
  const ss = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
  return YY + MM + DD + " " + hh + mm + ss;
}

watch([value2, selectedLine], ([newValue2, newLine]) => {
  const start_time = formatDate(newValue2[0]);
  const end_time = formatDate(newValue2[1]);
  fetchData(start_time, end_time, newLine);
});

async function fetchData(startTime, endTime, line = selectedLine.value) {
  const url = `http://10.64.35.32:8000/postgresql_data_api/get_DataPartcount_data/` +
              `?start_time=${startTime}&end_time=${endTime}&page_size=1000000000`;
  console.log(url);
  try {
    const response = await axios.get(url);
    const allData = response.data;
    
    const filteredData = allData.filter(item => 
      item.counttype === 'Good' && 
      item.assetnum.startsWith(line) &&
      !filteredAssets.value.includes(item.assetnum) 
    );
    
    const processedData = processHourlyProductionData(filteredData);
    initChart(processedData);
  } catch (error) {
    console.error(error);
  }
}

function processHourlyProductionData(data) {
  const dateHourlyData = {};
  
  data.forEach(item => {
    const timestamp = new Date(item.timestamp);
    const dateKey = `${timestamp.getFullYear()}-${timestamp.getMonth()+1}-${timestamp.getDate()}`;
    const hourKey = timestamp.getHours();
    const asset = item.assetnum;
    
    if (!dateHourlyData[dateKey]) {
      dateHourlyData[dateKey] = {};
    }
    
    if (!dateHourlyData[dateKey][hourKey]) {
      dateHourlyData[dateKey][hourKey] = {
        assets: {},
        startTime: new Date(timestamp.getFullYear(), timestamp.getMonth(), timestamp.getDate(), timestamp.getHours()),
      };
    }
    
    if (!dateHourlyData[dateKey][hourKey].assets[asset]) {
      dateHourlyData[dateKey][hourKey].assets[asset] = 0;
    }
    
    dateHourlyData[dateKey][hourKey].assets[asset]++;
  });
  
  const result = Object.keys(dateHourlyData).map(dateKey => {
    const hoursData = dateHourlyData[dateKey];
    const hoursArray = Object.keys(hoursData).map(hourKey => {
      const hourData = hoursData[hourKey];
      const startHour = hourData.startTime.getHours();
      const endHour = startHour + 1;
      
      return {
        assets: hourData.assets,
        timeRange: `${startHour}:00-${endHour}:00`,
      };
    });
    
    hoursArray.sort((a, b) => {
      const aTime = a.timeRange.split(':')[0];
      const bTime = b.timeRange.split(':')[0];
      return parseInt(aTime) - parseInt(bTime);
    });
    
    return {
      date: dateKey,
      hours: hoursArray
    };
  });
  
  result.sort((a, b) => new Date(a.date) - new Date(b.date));
  
  return result;
}
</script>

<style scoped>
h3 {
  color: black;
}

.block {
  padding: 20px;
  text-align: center;
}
</style>